package com.xxjh.brs.mvc.config;

import com.xxjh.brs.mvc.threadpool.MdcThreadPoolTaskExecutor;
import com.xxjh.brs.mvc.threadpool.MdcThreadPoolTaskScheduler;
import com.xxjh.brs.mvc.threadpool.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.*;

/**
 * @author CHENCHEN
 * @title 线程池配置类
 * @company 新兴际华科技（天津）有限公司
 * @create 2024-07-03 19:21
 */
@EnableAsync
@EnableScheduling
@Configuration
public class ThreadPoolConfig {

    // 核心线程池大小
    private static final int CORE_POOL_SIZE = 50;
    // 最大可创建的线程数
    private static final int MAX_POOL_SIZE = 200;
    // 队列最大长度
    private static final int QUEUE_CAPACITY = 1000;
    // 线程池维护线程所允许的空闲时间
    private static final int KEEP_ALIVE_SECONDS = 300;
    // 线程命名工厂
    private final ThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("thread-%d").build();
    // 线程池拒绝策略
    private final RejectedExecutionHandler rejectionHandler = new ThreadPoolExecutor.CallerRunsPolicy();

    // 辅助方法，用于统一配置线程池
    private void configureExecutor(ThreadPoolTaskExecutor executor, String prefix) {
        executor.setCorePoolSize(CORE_POOL_SIZE);
        executor.setMaxPoolSize(MAX_POOL_SIZE);
        executor.setQueueCapacity(QUEUE_CAPACITY);
        executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        executor.setThreadFactory(threadFactory);
        executor.setRejectedExecutionHandler(rejectionHandler);
        executor.setThreadNamePrefix(prefix);
    }

    /**
     * 瞬时任务下载线程池
     * 适用于执行非周期性的、一次性的任务，如HTTP请求处理、数据处理等。
     * 这些任务一旦提交就会尽快执行，没有固定的执行时间间隔。
     */
    @Bean(name = "instantTaskDownloadExecutor")
    public ThreadPoolTaskExecutor instantTaskDownloadExecutor() {
        ThreadPoolTaskExecutor executor = new MdcThreadPoolTaskExecutor();
        configureExecutor(executor, "instant-task-download-");
        return executor;
    }

    /**
     * 瞬时任务上传线程池
     * 适用于执行非周期性的、一次性的任务，如HTTP请求处理、数据处理等。
     * 这些任务一旦提交就会尽快执行，没有固定的执行时间间隔。
     */
    @Bean(name = "instantTaskUploadExecutor")
    public ThreadPoolTaskExecutor instantTaskUploadExecutor() {
        ThreadPoolTaskExecutor executor = new MdcThreadPoolTaskExecutor();
        configureExecutor(executor, "instant-task-upload-");
        return executor;
    }

    /**
     * 周期性任务线程池
     * 用于执行周期重复的任务，如定时检查数据库状态、清理缓存等。
     * 这类任务按照固定的间隔重复执行。
     */
    @Bean(name = "taskScheduler")
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(CORE_POOL_SIZE);
        scheduler.setThreadNamePrefix("scheduler-task-");
        scheduler.setRejectedExecutionHandler(rejectionHandler);
        scheduler.setRemoveOnCancelPolicy(true); // 取消的任务将从队列中移除
        scheduler.initialize();
        return scheduler;
    }

}
